#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef WIN32
#include <unistd.h>
#endif

#include <dicom/dicom.h>
#include "dicop.h"

struct PersonInfo {
    char name[32];
    char age[32];
    char height[32];
    char weight[32];
} Person;

callback_t SignalChangeHandler(callback_args_t args)
{
    printf("[%s] Change signal received\n", __func__);

    dicop_callback_get_args(args, 1, "name", Person.name);

    printf("New name: %s\n", Person.name);

    return 0;
}

int Terminate = 0;

callback_t SignalTerminateHandler(callback_args_t args)
{
    printf("[%s] Terminate signal received\n", __func__);

    Terminate = 1;

    return 0;
}

int main(void)
{
    int ConnID;
    struct dicop_app *ContactApp, *ErrorApp;
    int CallSession;
    int ret;

    bzero(&Person, sizeof(Person));

    dicop_init();

    PRINT_INFO("Connect to client ... ");
    ConnID = dicop_client_connect("127.0.0.1", 12250);

    /* APP query test */
    PRINT_INFO("OK\nQuerying ErrorApp ... ");
    ErrorApp = dicop_app_query(ConnID, "ErrorApp");
    if (!ErrorApp)
        PRINT_INFO("ErrorApp doesn't exist!\n");

    PRINT_INFO("Querying Contact ... ");
    ContactApp = dicop_app_query(ConnID, "Contact");

    if (ContactApp) {
        printf("OK\n");

        PRINT_INFO("Connect to signals ... ");
        dicop_signal_connect(ContactApp, "Change", SignalChangeHandler);
        dicop_signal_connect(ContactApp, "Terminate", SignalTerminateHandler);

        PRINT_INFO("OK\n[setPersonInfo] method test (kenny) ... ");
        dicop_method_call_no_reply(ContactApp, "setPersonInfo", "name", "kenny", "age", "29", "height", "170", "weight", "60");
        PRINT_INFO("OK\n[setPersonInfo] method test (chardi) ... ");
        dicop_method_call_no_reply(ContactApp, "setPersonInfo", "name", "chardi", "age", "27", "height", "158", "weight", "45");

        while (1) {
            /* Normal method call and reply test */
            PRINT_INFO("OK\n[getPersonInfo] method test (chardi) ... ");
            bzero(&Person, sizeof(Person));
            strcpy(Person.name, "chardi");
            CallSession = dicop_method_call(ContactApp, "getPersonInfo", "name", "chardi");
            dicop_method_call_get_reply(ContactApp, "getPersonInfo", CallSession, "age", Person.age, "height", Person.height, "weight", Person.weight);
            PRINT_INFO("OK\nReply of %s: age = %s, height = %s, weight = %s\n", Person.name, Person.age, Person.height, Person.weight);

            /* Fail method call and reply test */
            PRINT_INFO("[getPersonInfo] method test (kenny) ... ");
            bzero(&Person, sizeof(Person));
            strcpy(Person.name, "kenny");
            CallSession = dicop_method_call(ContactApp, "getPersonInfo", "name", Person.name);
            ret = dicop_method_call_get_reply(ContactApp, "getPersonInfo", CallSession, "age", Person.age, "height", Person.height, "weight", Person.weight);
            if (ret < 0) dicop_error_print(ret);
            printf("OK\nReply of %s: age = %s, height = %s, weight = %s\n", Person.name, Person.age, Person.height, Person.weight);

            /* Unknown method call test */
            PRINT_INFO("Unknown method call test ... \n");
            CallSession = dicop_method_call(ContactApp, "hellochardi", "name", Person.name);
            if (CallSession < 0) dicop_error_print(CallSession);

            PRINT_INFO("Checking for termination signal ...\n");
            if (Terminate) {
                PRINT_INFO("Got termination signal! Exiting ...\n");
                dicop_app_destroy(ContactApp);
                break;
            }
        }
    }
    else
        PRINT_INFO("ContactApp doesn't exist!\n");

    dicop_client_disconnect(ConnID);

    return 0;
}

